#include "VorbisDecoder.hpp"

#ifdef __WINDOWS__
#include <io.h>
#include <fcntl.h>
#endif

#ifdef __APPLE__
#ifdef __i386
#define OV_ENDIAN_ARG 0
#else
#define OV_ENDIAN_ARG 1
#endif
#endif

#ifdef __LINUX__
#include <endian.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define OV_ENDIAN_ARG 0
#else
#define OV_ENDIAN_ARG 1
#endif
#else
#define OV_ENDIAN_ARG 0
#endif

bool VorbisDecoder::load(const char* filename, bool silence) {
#ifdef __WIN32__
    if(ov_fopen(filename, &vf) < 0) {
        std::cout << "oggvorbis: Input does not appear to be an Ogg bitstream. (Windows)" << std::endl;
        return false;
    }
#else
    FILE *vorbisfile =  fopen(filename, "r");
    if (!vorbisfile) {
        std::cout << "oggvorbis: cannot open" << filename << std::endl;
        return false;
    }
    if(ov_open(vorbisfile, &vf, NULL, 0) < 0) {
        std::cout << "oggvorbis: Input does not appear to be an Ogg bitstream. (Linux & Mac)" << std::endl;
        return false;
    }
#endif
    vorbis_info * vi = ov_info(&vf, -1);
    channels = vi->channels;
    frequency= vi->rate;
    if(channels > 2){
        std::cout << "oggvorbis: No support for more than 2 channels!" <<std::endl;
        ov_clear(&vf);
        return false;
    }
    samples=ov_pcm_total(&vf, -1);
    seekable=ov_seekable(&vf);
    //bufferInitialized=false;
    return true;
}

void VorbisDecoder::close() {
    //free(buffer);
    ov_clear(&vf);
}

int VorbisDecoder::decode(float *data, unsigned long frames) {
    int current_section;
    float **tmp=(float**)malloc(sizeof(float)*channels);
    int r;//read
    for(r=0; r<frames; r++) {
        if(ov_read_float(&vf, &tmp, 1, &current_section)<=0) break;
        for(int c=0; c<channels; c++) {data[r+c]=tmp[c][0];
            std::cout << data[r+c] << " "<<std::endl;
        }
    }
    free(tmp);
    return r;
    /*if(!bufferInitialized) {
        buffer=(float**)malloc(sizeof(float)*channels*frames);
        bufferInitialized=true;
    }
    int read, total=0;
    while((read=ov_read_float(&vf, &buffer, frames-total, &current_section))>0) {
        //std::cout<<total<<"/"<<frames<<std::endl;
        for(int r=0; r<read; r++) {
            for(int c=0; c<channels; c++) data[total+r+c]=buffer[c][r];
        }
        total+=read;
    }
    //free(tmp);
    return total;*/
}

bool VorbisDecoder::seek(unsigned int frame) {
    if(!seekable) return false;
    ov_pcm_seek(&vf, frame);
    position=ov_pcm_tell(&vf);
}
